/****************************************************************************************
*                                                                                      *
*                          Projeto BioInfo - Lincs and CIn / UFPE                      *
*                                    07/10/2014                                        *
*																					   *
****************************************************************************************
* Descricao: Arquivo que contem funcoes da classe Canonic.                    *
****************************************************************************************
* Responsaveis: Jefferson Ramos(jrla)													   *
*                                                                                      */
/*                                                                                     *
****************************************************************************************/
#include <Canonic.hpp>


int Canonic::maximum (	
						int diag,
						int left,
						int up,
						int comparacao,
						TypeMat_direction *direction
						) //funcao auxiliar maximo
{
	if (diag < left) //Mach ganha de insersao
	{
		if (left >= up) {
			*direction = 1;
			return left; //Insersao
		}
		else {
			*direction = 0;
			return up; //Remocao
		}
	}
	else //Insersao ganha do Mach
	{
		if (diag < up) {
			*direction = 0;
			return up; //remocao
		}
		else {
			if (comparacao == 1) {
				*direction = 3;
				return diag; //mach
			}
			else {
				*direction = 2;
				return diag; //mach
			}
		}
	}
}


void Canonic::print_results()
{
	int taxa_individuals = 0;
	for (int i = 1; i <= num_individuals*alignment_by_individuals; i++){
		taxa_individuals += vector_taxa[i];

		if (i%alignment_by_individuals == 0){
			fprintf(TaxaOut, "%d\n", taxa_individuals);
			taxa_individuals = 0;
		}
	}
}


void Canonic::run()
{
	int *id = new int[1];

	id[0] = 0;
	canonic_needlemanwunsch( (void*)id );//canonico
}


int Canonic::vectors_malloc()
{
	query = (TypeQuery *)_aligned_malloc(sizeof(TypeQuery)*(alignment_by_individuals*TAMSEQ), 64);
		if (!query){ printf("ERROR: Alloc_query(size:%d)\n", (TAMSEQ)); return -1; }

	individuals = (TypeIndividuals *)_aligned_malloc((sizeof(TypeIndividuals)*TAMSEQ*alignment_by_individuals*num_individuals), 64);
		if (!individuals){ printf("ERROR: Alloc_individuals(size:%u)\n", (TAMSEQ*alignment_by_individuals*num_individuals)); return -1; }
	
	store_individuals = (TypeIndividuals *)_aligned_malloc((sizeof(TypeIndividuals)*(TAMSEQ / Byte_By_TwoBit)*alignment_by_individuals*num_individuals), 64);
		if (!individuals){ printf("ERROR: Alloc_store_individuals(size:%u)\n", ((TAMSEQ / Byte_By_TwoBit)*alignment_by_individuals*num_individuals)); return -1; }

	mat_direction = (TypeMat_direction*)_aligned_malloc(sizeof(TypeMat_direction)*TAMSEQ*TAMSEQ, 64);
		if (!mat_direction){ printf("ERROR: Alloc_mat_direction(size:%d)\n", (TAMSEQ*TAMSEQ)); return -1; }

	vector_taxa = (int*)_aligned_malloc(sizeof(int)*alignment_by_individuals*num_individuals, 64);
		if (!vector_taxa){ printf("ERROR: Alloc_taxa(size:%d)\n", num_individuals); return -1; }

	score_vector = (int *)_aligned_malloc(sizeof(int)*(TAMSEQ + 1), 64);
		if (!score_vector){ printf("ERROR: Alloc_score_vector(size:%d)\n", (TAMSEQ + 1)); return -1; }

	return 0;
}


void Canonic::read_input_individuals() {
	int i, k;

	fread(store_individuals, sizeof(TypeIndividuals), (TAMSEQ / Byte_By_TwoBit)*alignment_by_individuals*num_individuals, BD_nucleotideos);
	store_individuals[(TAMSEQ / 4)*alignment_by_individuals*num_individuals] = '\0';

	for (i = 0, k = 0; i < (TAMSEQ / Byte_By_TwoBit)*alignment_by_individuals*num_individuals; i++){

		individuals[k++] = (MASK_NCL1 & store_individuals[i]) + 48;
		individuals[k++] = ((MASK_NCL2 & store_individuals[i]) >> 2) + 48;
		individuals[k++] = ((MASK_NCL3 & store_individuals[i]) >> 4) + 48;
		individuals[k++] = ((MASK_NCL4 & store_individuals[i]) >> 6) + 48;
	}
	individuals[k] = '\0';
}


void Canonic::read_input_query() {

	int j, k = 0;
	TypeQuery nucleotideo;

	fj(0, (TAMSEQ / Byte_By_TwoBit)*alignment_by_individuals*query_compare){
		fread(&nucleotideo, sizeof(TypeQuery), 1, BD_nucleotideos);

		if (j >= ((TAMSEQ / Byte_By_TwoBit)*alignment_by_individuals*(query_compare - 1))){
			query[k++] = (MASK_NCL1 & nucleotideo) + 48;
			query[k++] = ((MASK_NCL2 & nucleotideo) >> 2) + 48;
			query[k++] = ((MASK_NCL3 & nucleotideo) >> 4) + 48;
			query[k++] = ((MASK_NCL4 & nucleotideo) >> 6) + 48;
		}
	}
	query[k] = '\0';
}



